package com.liuqianfei.markdown;

/**
 * 配置
 * 
 */
public class Configuration
{
    final boolean safeMode;
    final boolean panicMode;
    final String encoding;
    final Decorator decorator;
    final BlockEmitter codeBlockEmitter;
    final boolean forceExtendedProfile;
    final boolean allowSpacesInFencedDelimiters;
    final SpanEmitter specialLinkEmitter;

    /**
     * <p>
     * <code>process</code>方法默认配置，非安全模式。
     * </p>
     *
     * <ul>
     * <li><code>safeMode = false</code></li>
     * <li><code>encoding = UTF-8</code></li>
     * <li><code>decorator = DefaultDecorator</code></li>
     * <li><code>codeBlockEmitter = CodeBlockEmitter</code></li>
     * </ul>
     */
    public final static Configuration DEFAULT = Configuration.builder().build();

    /**
     * <p>
     * 默认安全模式配置。
     * </p>
     *
     * <ul>
     * <li><code>safeMode = true</code></li>
     * <li><code>encoding = UTF-8</code></li>
     * <li><code>decorator = DefaultDecorator</code></li>
     * <li><code>codeBlockEmitter = null</code></li>
     * </ul>
     */
    public final static Configuration DEFAULT_SAFE = Configuration.builder().enableSafeMode().build();

    /**
     * Constructor.
     */
    Configuration(final boolean safeMode, final String encoding, final Decorator decorator, final BlockEmitter codeBlockEmitter, final boolean forceExtendedProfile, final SpanEmitter specialLinkEmitter, final boolean allowSpacesInFencedDelimiters, final boolean panicMode)
    {
        this.safeMode = safeMode;
        this.encoding = encoding;
        this.decorator = decorator;
        this.codeBlockEmitter = codeBlockEmitter;
        this.forceExtendedProfile = forceExtendedProfile;
        this.specialLinkEmitter = specialLinkEmitter;
        this.allowSpacesInFencedDelimiters = allowSpacesInFencedDelimiters;
        this.panicMode = panicMode;
    }

    /**
     * 创建新的Builder实例。
     *
     * @return Builder实例
     */
    public static Builder builder()
    {
        return new Builder();
    }

    /**
     * 配置构建器。
     *
     * @author liuqianfei
     */
    public static class Builder
    {
        private boolean safeMode = false;
        private boolean panicMode = false;
        private boolean forceExtendedProfile = true;//false;
        private boolean allowSpacesInFencedDelimiters = true;
        private String encoding = "UTF-8";
        private Decorator decorator = new ExtDecorator();// new DefaultDecorator();
        private BlockEmitter codeBlockEmitter = new CodeBlockEmitter();
        private SpanEmitter specialLinkEmitter = null;

        Builder()
        {
        }

        /**
         * 开启HTML标签安全模式。
         *
         * 默认： <code>false</code>
         *
         * @return This builder
         */
        public Builder enableSafeMode()
        {
            this.safeMode = true;
            return this;
        }

        /**
         * 强制开启可扩展模式。
         * 
         * 默认： <code>false</code>
         *
         * @return This builder.
         */
        public Builder forceExtentedProfile()
        {
            this.forceExtendedProfile = true;
            return this;
        }

        /**
         * 设置HTML标签安全模式。
         *
         * 默认： <code>false</code>
         *
         * @param flag <code>true</code>，则设置为安全模式
         * @return This builder
         */
        public Builder setSafeMode(final boolean flag)
        {
            this.safeMode = flag;
            return this;
        }

        /**
         * 设置编码。
         *
         * 默认：<code>&quot;UTF-8&quot;</code>
         *
         * @param encoding 编码字符串
         * @return This builder
         */
        public Builder setEncoding(final String encoding)
        {
            this.encoding = encoding;
            return this;
        }

        /**
         * 设置标签装饰器。
         *
         * 默认：<code>DefaultDecorator()</code>
         *
         * @param decorator 装饰器
         * @return This builder
         * @see DefaultDecorator
         */
        public Builder setDecorator(final Decorator decorator)
        {
            this.decorator = decorator;
            return this;
        }

        /**
         * 设置多行代码块处理器。
         *
         * 默认：<code>CodeBlockEmitter()</code>
         *
         * @param emitter BlockEmitter
         * @return This builder
         * @see BlockEmitter
         */
        public Builder setCodeBlockEmitter(final BlockEmitter emitter)
        {
            this.codeBlockEmitter = emitter;
            return this;
        }

        /**
         * Sets the emitter for special link spans ([[ ... ]]).
         *
         * @param emitter The emitter.
         * @return This builder.
         */
        public Builder setSpecialLinkEmitter(final SpanEmitter emitter)
        {
            this.specialLinkEmitter = emitter;
            return this;
        }

        /**
         * (Dis-)Allows spaces in fenced code block delimiter lines.
         *
         * @param allow 是否允许有空格
         * @return This builder.
         */
        public Builder setAllowSpacesInFencedCodeBlockDelimiters(final boolean allow)
        {
            this.allowSpacesInFencedDelimiters = allow;
            return this;
        }

        /**
         * 允许你开启'panicMode'。当'panicMode'模式被开启，任何遇到的{@code <}都将被转为{@code &lt;}
         *
         * @param panic 是否允许panic模式，默认为<code>false</code>
         * @return This builder.
         */
        public Builder setEnablePanicMode(final boolean panic)
        {
            this.panicMode = panic;
            return this;
        }

        /**
         * 允许你开启'panicMode'。当'panicMode'模式被开启，任何遇到的{@code <}都将被转为{@code &lt;}
         *
         * @return This builder.
         */
        public Builder enablePanicMode()
        {
            this.panicMode = true;
            return this;
        }

        /**
         * 创建一个configuration实例。
         *
         * @return Configuration实例
         */
        public Configuration build()
        {
            return new Configuration(this.safeMode, this.encoding, this.decorator, this.codeBlockEmitter, this.forceExtendedProfile, this.specialLinkEmitter, this.allowSpacesInFencedDelimiters, this.panicMode);
        }
    }
}
